#include "ATMOS_NetworkManagerServer.h"
#include "ATMOS_NetworkConnectionInfo.h"
#include "ATMOS_Packet.h"

#include "RakPeerInterface.h"
#include "BitStream.h"
#include "MessageIdentifiers.h"

#include <iostream>
#include <sstream>

using namespace ATMOS;

NetworkManagerServer::NetworkManagerServer()
{
}

NetworkManagerServer::~NetworkManagerServer()
{
}

void NetworkManagerServer::initialize( const NetworkConnectionInfo &info )
{
	NetworkManager::initialize( info );

	ATMOS_LOG_FUNC();	
	RakNet::SocketDescriptor socketDescriptor( info.serverPort, 0 );

	mPeerInterface = RakNet::RakPeerInterface::GetInstance();
	mPeerInterface->SetIncomingPassword( 
		info.connectionPassword.c_str(),
		strlen( info.connectionPassword.c_str() ) );
	mPeerInterface->SetTimeoutTime( 30000, RakNet::UNASSIGNED_SYSTEM_ADDRESS );
	RakNet::StartupResult result = 
		mPeerInterface->Startup( info.maxConnections, &socketDescriptor, 1 );
	switch( result )
	{
		case RakNet::RAKNET_STARTED: 
			break;
		case RakNet::RAKNET_ALREADY_STARTED:
			ATMOS_THROW_RT("raknet already started");
			break;
		case RakNet::INVALID_SOCKET_DESCRIPTORS: 
			ATMOS_THROW_RT("invalid socket descriptors");
			break;
		case RakNet::INVALID_MAX_CONNECTIONS: 
			ATMOS_THROW_RT("invalid max connections");
			break;
		case RakNet::SOCKET_PORT_ALREADY_IN_USE: 
			ATMOS_THROW_RT("socket port already in use");
			break;
		case RakNet::SOCKET_FAILED_TO_BIND: 
			ATMOS_THROW_RT("failed to bind socket");
			break;
		case RakNet::SOCKET_FAILED_TEST_SEND: 
			ATMOS_THROW_RT("failed test send");
			break;
		case RakNet::FAILED_TO_CREATE_NETWORK_THREAD: 
			ATMOS_THROW_RT("failed to create network thread");
			break;
	}

	mPeerInterface->SetMaximumIncomingConnections( info.maxConnections );
	mPeerInterface->SetOccasionalPing( info.occasionalPing );
	mPeerInterface->SetUnreliableTimeout( info.unreliableTimeout );
}